<template>
  <n-popover trigger="click" :width="260" class="data-tables-toolbar-right-popover" placement="bottom-end"
             :content-style="{ padding: '5px 0' }">
    <template #trigger>
      <n-tooltip trigger="hover" size="small" placement="top-end">
        <template #trigger>
          <n-icon size="20">
            <Columns/>
          </n-icon>
        </template>
        列设置
      </n-tooltip>
    </template>
    <template #header>
      <div class="data-tables-toolbar-right-popover-title">
        <div class="data-tables-toolbar-right-popover-title-checkbox">
          <n-checkbox v-model:checked="checkAll" :indeterminate="checkedIndeterminate" @update:checked="onCheckAll">
            列展示
          </n-checkbox>
        </div>
        <div class="data-tables-toolbar-right-popover-title-button">
          <n-button text type="primary" size="small" @click="resetColumns">重置</n-button>
        </div>
      </div>
    </template>
    <div class="data-tables-toolbar-right-popover-column">
      <n-checkbox-group v-model:value="checkColumnList" @update:value="onChange">
        <n-list hoverable>
          <vue-draggable-next :list="columnsList" animation="300" item-key="key" :move="onMove" @end="draggableEnd">
            <template v-for="element in columnsList">

              <div class="data-tables-toolbar-right-popover-column-checkbox">
                <n-list-item>
              <span class="data-tables-toolbar-right-popover-column-checkbox-drag-icon">
                <n-icon size="18">
                   <DragOutlined/>
                 </n-icon>
                     &nbsp; <n-checkbox :value="element.key" :label="element.title"/>
              </span>
                  <div class="data-tables-toolbar-right-popover-column-checkbox-fixed-item">
                    <n-icon size="16"
                            :color="element.fixed === 'left' ? ThemesColor.appTheme : undefined"
                            @click="fixedColumn(element, 'left')">
                      <VerticalRightOutlined/>
                    </n-icon>
                    <n-divider vertical/>
                    <n-icon size="16" :color="element.fixed === 'right' ? ThemesColor.appTheme : undefined"
                            @click="fixedColumn(element, 'right')">
                      <VerticalLeftOutlined/>
                    </n-icon>
                  </div>
                </n-list-item>
              </div>
            </template>
          </vue-draggable-next>
        </n-list>
      </n-checkbox-group>
    </div>
  </n-popover>
</template>

<script lang="ts" setup>
import {ref, toRaw, unref, watchEffect} from 'vue'
import {Columns} from '@vicons/tabler';
import {useTableContext} from '../../hooks/useTableContext.ts';
import {ColumnKey, TableBaseColumn} from 'naive-ui/lib/data-table/src/interface';
import {cloneDeep} from 'lodash-es';
import { VueDraggableNext} from 'vue-draggable-next'
import {DragOutlined, VerticalLeftOutlined, VerticalRightOutlined} from '@vicons/antd';
import {ThemesColor} from '@/config'

const table: any = useTableContext();
//全选  默认true
const checkAll = ref<boolean>(true);
const checkedIndeterminate = ref<boolean>(false);
//选中字段
const checkColumnList = ref<ColumnKey[]>([]);
const defaultCheckColumnList = ref<ColumnKey[]>([]);
//列
const columnsList = ref<TableBaseColumn[]>([]);
//缓存列
const cacheColumnsList = ref<TableBaseColumn[]>([]);

const filterColumns = (): TableBaseColumn[] => {
  const columns: TableBaseColumn[] = getColumns();
  return columns.filter((item) => {
    return (
        item.key != "action" &&
        item.title != "操作" &&
        item.key != "no" &&
        item.type != "selection"
    );
  });
}

//初始化
function init() {
  const filters: TableBaseColumn[] = filterColumns();
  const filter_columns_list = filters.map((item: any) => item.key);
  checkColumnList.value = filter_columns_list;
  defaultCheckColumnList.value = filter_columns_list;
  if (!columnsList.value.length) {
    columnsList.value = filters;
    cacheColumnsList.value = cloneDeep(filters);
  }
}

//获取表头中的列
const getColumns = (): TableBaseColumn[] => {
  const newColumns: TableBaseColumn[] = [];
  table.getColumns().forEach((item: TableBaseColumn) => {
    newColumns.push(item);
  });
  return newColumns;
}
watchEffect(() => {
  const columns = table.getColumns();
  if (columns.length) {
    init();
  }
})
//全选、反选
const onCheckAll = (e: boolean) => {
  let checkedList = table.getCacheColumns(true);
  if (e || !e && checkedIndeterminate.value) {
    checkColumnList.value = checkedList;
    updateColumns(checkedList);
    checkedIndeterminate.value=false;
    checkAll.value = true;
  } else {
    checkColumnList.value = [];
    updateColumns([]);
  }

}
//重置
const resetColumns = () => {
  updateColumns(cacheColumnsList.value);
  checkedIndeterminate.value = false;
  checkAll.value = true;
  columnsList.value = cacheColumnsList.value;
}
const onChange = (newColumns: string[]) => {
  updateColumns(newColumns);
  const CacheColumnsCount = table.getCacheColumns(true).length;
  if (newColumns.length == 0) {
    checkedIndeterminate.value = false;
    checkAll.value = false;
  } else {
    checkedIndeterminate.value = CacheColumnsCount != newColumns.length;
  }
}
//移动
const onMove = (e: any) => {
  return e.draggedContext.element.draggable !== false;
}
//拖拽更换位置
const draggableEnd = () => {
  const checkList: TableBaseColumn[] = toRaw(unref(columnsList));
  const new_checkList = toRaw(checkList).map((item: any) => toRaw(item));
  let intersection = new_checkList.filter(item => filterColumns().find(b => b.key === item.key));
  updateColumns(intersection);

}
const fixedColumn = (item:any, fixed: string) => {
  if (!checkColumnList.value.includes(item.key)) return;
  let columns: TableBaseColumn[] = filterColumns();
  const isFixed = item.fixed === fixed ? undefined : fixed;
  let index: number = columns.findIndex((res: TableBaseColumn) => res.key === item.key);
  if (index !== -1) {
    // @ts-ignore
    columns[index]['fixed'] = isFixed;
  }
  table.setCacheColumnsField(item.key, {fixed: isFixed});
  // @ts-ignore
  columnsList.value[index]['fixed'] = isFixed;
  updateColumns(columns);
}
const updateColumns = (columns: string[] | TableBaseColumn[]) => {
  table.setColumns(columns);
}

</script>

<style scoped lang="scss">
.data-tables {
  &-toolbar-right-popover {
    &-title {
      display: flex;
      justify-content: space-between;
      padding: 3px 0;

      &-checkbox {
        display: flex;
        justify-content: flex-start;
      }

      &-button {
        display: flex;
        justify-content: flex-end;
      }
    }
  }
}

:deep(.data-tables-toolbar-right-popover-column-checkbox) {
  .n-list-item {
    padding: 5px;
    cursor: pointer;
    border-radius: 0;

    .n-list-item__main {
      display: flex;
      justify-content: space-between;

      i {
        position: relative;
        top: 4px;
      }
    }
  }
}
</style>